import './App.css';
import { Provider, useDispatch, useSelector } from 'react-redux';
import store from './store';

import { fetchFoodsList } from './store/modules/takeaway';
import { useEffect, useReducer, useState, useMemo, memo, useCallback, forwardRef, useRef, useImperativeHandle } from 'react';
import { getChannelAPI } from '@/apis/article'

import { create } from 'zustand'

const useStore = create((set) => {
  return {
    // 状态数据
    // 修改数据的方法
    count: 0,
    channelList: [],
    inc: () => {
      set((state) => ( {count: state.count + 1 } )) // 基于原数据，返回一个新的数据
      // set({ // 不需要原数据，直接返回新数据
      //   count: 100
      // })
    },
    fetchChannelList: async () => {
      const res = await getChannelAPI()
      console.log(res)
      set({ channelList: res.data.channels })
    }
  }
})

/**
 * 定义reducer函数，根据不同的action 返回不同的状态
 * 组件中调用useReducer(reducer, 0) => [state, dispatch]
 * 调用dispatch({type: 'INC'}) => 通知reducer产生一个新的状态 使用这个新的状态更新UI
 */
function reducer(state, action) {
  switch (action.type) {
    case 'INC':
      return state + 1;
    case 'DEC':
      return state - 1;
    case 'SET':
      return action.payload;
    default:
      return state;
  }
}

/**
 * useMemo
 * 缓存：消耗非常大的计算
 * 一般常规的计算用不上
 */
// 计算斐波那契数列之和
function sumFibonacci(n) {
  console.log('计算函数执行了')
  if (n < 3) {
    return n;
  }
  return sumFibonacci(n - 1) + sumFibonacci(n - 2);
}

// 子跟父一起渲染了，用memo，子组件就不会渲染了，只有props发生变化的时候才会重新渲染
const MemoSon = memo(function Son({ list }) {
  console.log('我是子组件，我重新渲染了')
  return <div>this is son {list}</div>
})

const Input = memo(function Input({ value, onChange }) {
  console.log('我是子组件，我重新渲染了')
  return <input value={value} onChange={onChange} />
})

const Input2 = forwardRef((props, ref) => {
  const inputRef = useRef(null)
  const focusHandler = () => {
    inputRef.current.focus()
  }

  useImperativeHandle(ref, () => {
    return {
      focusHandler
    }
  })
  return <input type="text" ref={inputRef} />
})

function App() {
  // const [state, dispatch2] = useReducer(reducer, 0);

  // const dispatch = useDispatch();
  // useEffect(() => {
  //   dispatch(fetchFoodsList())
  // }, [dispatch]);

  // const { foodsList } = useSelector(state => state.foods);

  // const [count1, setCount1] = useState(0)

  // const result = useMemo(() => {
  //   return sumFibonacci(count1)
  // }, [count1])


  // const [count2, setCount2] = useState(0)

  // const [count3, setCount3] = useState(0)

  // const list = [1, 2, 3] // 引用类型，每次传递都会引发子组件更新，即使数据没有发生变化
  // const list = useMemo(() => { // 用useMemo来缓存下，这样就不会引发子重新渲染了
  //   return [1, 2 , 3]
  // }, [])

  // const [count4, setCount4] = useState(0)

  // const changeHandler = useCallback((value) => {
  //   console.log(value)
  // }, [])

  // const inputRef = useRef(null)
  // const focusHandler = () => {
  //   inputRef.current.focusHandler()
  // }

  const { count, channelList, inc, fetchChannelList } = useStore()
  useEffect(() => {
    fetchChannelList()
  }, [fetchChannelList])
  return (
      <div className="App">
        {/* {foodsList.map((item, index) => {
          return <div key={index}>{item}</div>
        })}
        
        <button onClick={() => dispatch2({ type: 'DEC' })}>-</button>
        {state}
        <button onClick={() => dispatch2({ type: 'INC' })}>+</button>
        <button onClick={() => dispatch2({ type: 'SET', payload: 100})}>更新</button>

        <br />

        <button onClick={() => setCount1(count1 + 1)}>change count1: {count1}</button>
        <button onClick={() => setCount2(count2 + 1)}>change count2: {count2}</button>
        {result}


        <br /> */}

        {/* <button onClick={() => setCount3(count3 + 1)}>change count3: {count3}</button>
        <MemoSon list={list} /> */}

        {/* <Input onChange={changeHandler} />
        <button onClick={() => setCount4(count4 + 1)}>change count4: {count4}</button> */}

        {/* <Input2 ref={inputRef} />
        <button onClick={focusHandler}>foucus</button> */}

        <button onClick={inc}>zustand: {count}</button>
        <ul>
          {channelList.map((item) => {
            return <li key={item.id}>{item.name}</li>
          })}
        </ul>
      </div>
  );
}





export default App;
